Optimize API calls and enhance concurrency in TraktRepository - #122
Conversation
💡 What: Implemented an ephemeral cache (ConcurrentHashMap) during the parallel Continue Watching enrichment loops in TraktRepository.kt. The cache ensures that if multiple episodes of the same season are queried simultaneously, only one API call goes out and the other queries await the result. 🎯 Why: Previously, enrichContinueWatchingItems fetched season information via tmdbApi.getTvSeason() for every Continue Watching item synchronously inside its coroutine. In scenarios where a user is re-watching or has multiple items from the same season of a show, it fired identical network calls concurrently leading to unnecessary network/CPU utilization. 📊 Measured Improvement: Due to difficulties instantiating TraktRepository without Roboelectric or extensive mocks of DataStore, I have skipped creating a formal Android benchmark test suite instance to measure this precisely in CI. However, logically, a user with N items of the same season went from O(N) API calls down to O(1), removing network roundtrip overhead entirely for N-1 items during parallel awaitAll() execution.
💡 What: Implemented an ephemeral cache using `putIfAbsent` and `CompletableDeferred` during the parallel Continue Watching enrichment loops in TraktRepository.kt. The cache ensures that if multiple episodes of the same season are queried simultaneously, only one API call goes out and the other queries await the result via `putIfAbsent`. 🎯 Why: Previously, enrichContinueWatchingItems fetched season information via tmdbApi.getTvSeason() for every Continue Watching item synchronously inside its coroutine. In scenarios where a user is re-watching or has multiple items from the same season of a show, it fired identical network calls concurrently leading to unnecessary network/CPU utilization. 📊 Measured Improvement: Due to difficulties instantiating TraktRepository without Roboelectric or extensive mocks of DataStore, I have left the benchmark test as a documented placeholder. However, logically, a user with N items of the same season went from O(N) API calls down to O(1), removing network roundtrip overhead entirely for N-1 items during parallel awaitAll() execution.
- Replaced multiple `getTvSeason` API calls with a single `getTvDetails` call - Updated API models `TmdbTvDetails` and `TmdbTvSeason` - Abstracted caching logic to `ensureSeasonEpisodeCountsCached`
…s and add per-show in-flight guard to avoid concurrent API calls
What: Replaced the sequential forEach loop in cleanupTraktPlaybackProgress with a parallel execution pattern using coroutineScope, async, and awaitAll. Wrapped the network requests with a Semaphore(5) to bound concurrency to 5 parallel requests. Why: The previous implementation was suffering from an N+1 Database Operation loop. For each stale record, it performed a sequential network request (supabaseApi.deleteWatchHistory) to Supabase. This resulted in significant I/O delays proportional to the number of stale records. Measured Improvement: Simulated a 75ms network latency for the Supabase network call across 50 stale playback records in a benchmark test. Baseline (Sequential time): ~3766ms. Improved (Concurrent time with Semaphore 5): ~754ms. Speedup: ~5.0x
- Add supabaseAuthMutex to serialize auth repository refresh calls in executeSupabaseCall to prevent parallel DataStore writes and conflicting requests. - Rethrow CancellationException when cleaning up stale playbacks so the concurrent mapped tasks observe regular coroutine semantics.
…331` Docstrings generation was requested by @Himanth-reddy. The following files were modified: * `IptvBenchmark.kt` * `app/src/main/kotlin/com/arflix/tv/data/repository/IptvRepository.kt` These files were ignored: * `app/src/test/kotlin/com/arflix/tv/data/repository/IptvBenchmarkTest.kt` These file types are not supported: * `update_iptv_repo.patch`
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
The concurrency work in this PR is genuinely valuable — moving However, this PR cannot be merged as-is because it also adds a large number of developer scratchpad / AI-assistant artifacts at the repo root that should not ship with the app. Please remove the following before merge: One-off patch scripts (all at repo root):
Misplaced Kotlin file:
Quick cleanup: \\�ash After that cleanup the remaining diff (~6 production files + 2 tests) is the real change and is worth a careful re-review before merge, since
Happy to give it a full review once the scratchpad files are gone. |
|
Thanks for addressing every concern from the earlier review. Re-audited the final diff against current Blockers resolved:
Three original concerns verified:
Additional fixes from the review-comment iterations that I also verified:
Minor nits (not blockers, not addressing them):
Mergeability: Squash-merging now. Thanks for the thorough follow-through — this is a genuinely valuable concurrency cleanup that lays the groundwork for richer TV metadata (the new |
This pull request introduces substantial improvements to concurrency handling and data enrichment in the IPTV and Trakt repositories. The most significant changes include refactoring blocking thread pool operations to use coroutines for parallel network requests, optimizing TMDB season data enrichment with a coroutine-safe cache, and enhancing error handling and progress tracking during EPG data fetches. Additionally, new data models were added to support richer TV details.
Concurrency and Parallelism Improvements
IptvRepositoryto use coroutines with limited parallelism, improving efficiency and scalability for fetching EPG and channel data. This includes new coroutine-based implementations for fetching Xtream EPG listings and short EPG data, replacing manual thread pool management. [1] [2] [3] [4] [5]IptvBenchmark.kt) to compare thread pool and coroutine performance for parallel tasks.Network and API Handling Enhancements
requestJsonmethod inIptvRepositoryto a suspend function using OkHttp's async API, making network requests cancellable and coroutine-friendly.EPG Fetching and Progress Reporting
Trakt Repository Data Enrichment
TraktRepository, preventing duplicate network requests when enriching "continue watching" items and ensuring efficient concurrent access. [1] [2] [3]TraktSyncServiceto run in parallel with limited concurrency, improving sync speed and reliability. [1] [2]Data Model Extensions
TmdbTvSeasondata class and included aseasonsfield inTmdbTvDetailsto support richer TV metadata. [1] [2]These changes modernize the codebase's approach to concurrency, improve network efficiency, and lay the groundwork for richer media metadata support.